package com.zw.blog.web.admin;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.zw.blog.exception.NotFoundException;
import com.zw.blog.po.Blog;
import com.zw.blog.po.User;
import com.zw.blog.service.BlogService;
import com.zw.blog.service.TagService;
import com.zw.blog.service.TypeService;
import com.zw.blog.vo.BlogQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import static com.zw.blog.util.UploadUtils.*;

@Controller
@RequestMapping("/admin")
public class BlogController {

    private static final String INPUT = "admin/blogs-input";
    private static final String LIST = "admin/blogs";
    private static final String REDIRECT_LIST = "redirect:/admin/blogs";

    @Autowired
    private BlogService blogService;

    @Autowired
    private TypeService typeService;

    @Autowired
    private TagService tagService;

    @GetMapping("/blogs")
    public String list(@PageableDefault(size = 5, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
                       BlogQuery blog, Model model) {
        model.addAttribute("types", typeService.listType());
        model.addAttribute("tags", tagService.listTag());
        /*blog.setEnableRecommend(true); //希望每次默认展示推荐（非私密）的
        blog.setPublished(true);*/
        model.addAttribute("page", blogService.listBlog(pageable, blog));
        return LIST;
    }

    @PostMapping("/blogs/search")
    public String search(@PageableDefault(size = 5, sort = {"updateTime"}, direction = Sort.Direction.DESC) Pageable pageable,
                       BlogQuery blog, Model model) {
        model.addAttribute("page", blogService.listBlog(pageable, blog));
        return LIST + " :: blogList"; //返回blogs页面下的blogList片段
    }

    private void setTypeAndTag(Model model) {
        model.addAttribute("types", typeService.listType());
        model.addAttribute("tags", tagService.listTag());
    }
    @GetMapping("/blogs/input")//和修改公用一个页面的时候方便用哪个对象报错
    public String input(Model model) {
        model.addAttribute("blog", new Blog());
        setTypeAndTag(model);
        return INPUT;
    }

    @GetMapping("/blogs/{id}/input")
    public String editInput(@PathVariable Long id, Model model) {
        Blog blog  = blogService.getBlog(id);
        blog.initTagIds();
        model.addAttribute("blog", blog);
        setTypeAndTag(model);
        return INPUT;
    }

    /*封装提交的时候，封装到Blog里 是按照name封装到Blog的各个属性中*/
    @PostMapping("/blogs")
    public String post(@RequestParam boolean autoSubmit, Blog blog, RedirectAttributes attributes, Model model, HttpSession session) {
        blog.setUser((User) session.getAttribute("user"));
        blog.setType(typeService.getOrCreateType(blog.getTypeId())); //由于之前name设置的type.id???
        blog.setTags(tagService.listTag(blog.getTagIds())); //神奇的操作
        blog.setUpdateTime(new Date());
        Blog b;
        if (blog.getId() == null) {
            b = blogService.saveBlog(blog);

            /*if (autoSubmit) {
                return "redirect:/admin/blogs/" + b.getId() + "/input";
            }*/
        } else { //如果不为空，则是重新编辑博客，需要更新不然前端无输入的属性会自动为空
            b = blogService.updateBlog(blog.getId(), blog);
        }

        if (!autoSubmit) {
            if (b == null) {
                attributes.addFlashAttribute("message", "操作失败");
                return REDIRECT_LIST;
            } else {
                //attributes.addFlashAttribute("message", "操作成功");
                model.addAttribute(blogService.getAndConvert(b.getId()));
                return "blog";
            }
        } else { //autosave时返回空页面
            return "redirect:/admin/autosave";
        }
    }

    @ResponseBody
    @GetMapping("/autosave")
    public void autosave() {}

    @PostMapping("/blogs/upload/firstPicture")
    public String uploadFirstPicture(@RequestParam(required = false) String url,
                                     @RequestHeader(required = false) String localFileName,
                                     HttpServletRequest request, Model model) throws IOException {
        String fileName;
        if (url != null) {
            fileName = uploadHttpImage(url);
            if (fileName.startsWith("E")) {
                model.addAttribute("message", fileName);
                return INPUT + " :: firstPictureUpload";
            }
        } else if (localFileName != null) {
            InputStream in = request.getInputStream();
            fileName = uploadLocalImage(localFileName, in);
        } else {
            throw new NotFoundException("没有文件上传！");
        }
        model.addAttribute("path", fileName);
        model.addAttribute("message", "上传终于成功了！！");
        return INPUT + " :: firstPictureUpload";
    }

    @ResponseBody
    @PostMapping("/blogs/upload/editorPicture")
    public JSONObject uploadEditorPicture(HttpServletRequest request, HttpServletResponse response,
                                          @RequestParam(value = "editormd-image-file") MultipartFile attach) throws JSONException {
        JSONObject jsonObject = new JSONObject();

        try {
            request.setCharacterEncoding("utf-8");
            response.setHeader("Content-Type", "text/html");
            String rootPath = ABSOLUTE_BLOG_IMAGES_PATH + EDITOR_IMAGES_PATH;
            File filePath = new File(rootPath);
            if (!filePath.exists()) {
                filePath.mkdirs();
            }
            // 最终文件名
            String fileName = outputFile(rootPath, BLOG_IMAGES_PATH + EDITOR_IMAGES_PATH,
                    getUUID() + "." + getLocalType(attach.getOriginalFilename()), attach.getInputStream());
            // 下面response返回的json格式是editor.md所限制的，规范输出就OK
            jsonObject.put("success", 1);
            jsonObject.put("message", "上传成功");
            jsonObject.put("url", fileName);
        } catch (Exception e) {
            jsonObject.put("success", 0);
        }
        return jsonObject;
    }

    @GetMapping("/blogs/{id}/delete")
    public String delete(@PathVariable Long id, RedirectAttributes attributes) {
        blogService.deleteBlog(id);
        attributes.addFlashAttribute("message", "删除成功");
        return REDIRECT_LIST;
    }
}
